package cz.czu.pef.DataModelling;

import java.util.*;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cz.czu.pef.DataModelling.utils.Lazy;

/**
 * This entity represents concrete employee role in the company (role instance). Role itself is defined by related RoleType.
 * 
 * @author rstribrn
 *
 */
@Entity
@Table(name="ROLES")
@ManagedBean(name="role")
@ViewScoped
@Component
@Scope(value="prototype")
public class Role extends IdPersistenceObject
{
	private static final long serialVersionUID = 8392953561903669343L;

	/*
	 * Entity attributes
	 */

	@ManyToOne(fetch = FetchType.EAGER, targetEntity=RoleType.class, optional=false, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
	private RoleType roleType;

	/*
	 * Relations
	 */
	@ManyToMany(fetch = FetchType.LAZY, targetEntity = Employee.class, mappedBy = "roles", cascade=CascadeType.ALL) // all cascades!
	private Set<Employee> employees;

	protected Role()
	{
		super();
	}

	public Role(RoleType roleType)
	{
		super();
		this.roleType = roleType;
	}

	public RoleType getRoleType()
	{
		return roleType;
	}

	public void setRoleType(RoleType roleType)
	{
		this.roleType = roleType;
	}

	@Lazy
	@Transactional(readOnly=true, propagation=Propagation.REQUIRED)
	public Set<Employee> getEmployees()
	{
		return employees;
	}
	@Lazy
	@Transactional(readOnly=true, propagation=Propagation.REQUIRED)
	public List<Employee> getEmployeesAsList()
	{
		return new ArrayList<Employee>(getEmployees());
	}

	@Lazy
	@Transactional(readOnly=true, propagation=Propagation.REQUIRED)
	@Override
	public String toString()
	{
		StringBuilder builder = new StringBuilder();
		builder.append("Role [roleType=");
		builder.append(roleType);
		builder.append(", toString()=");
		builder.append(super.toString());
		builder.append("]");
		return builder.toString();
	}

	/**
	 * Can be removed (in cascade).
	 */
	@Override
	public boolean canBeRemoved()
	{
		return true;
	}
}
